package com.macllvm.whale.net;

import android.util.Log;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Arrays;
import java.util.Iterator;
import java.io.IOException;
import com.macllvm.whale.protocol.ProtocolBase;
import com.macllvm.whale.protocol.ProtocolController;


public  class  UDPServer extends Thread {
    private static final String TAG = "UDPServer";
    private DatagramChannel mChannel;
    private Selector mSelector;
    private boolean isRunning = false;
    private ProtocolController mController;
    private ByteBuffer mBuffer;

    public UDPServer(ProtocolController c) throws IOException {
        mController = c;
        mChannel = DatagramChannel.open();
        mChannel.configureBlocking(false);
        mChannel.socket().bind(new InetSocketAddress(ProtocolBase.IPMSG_PORT));
        mChannel.socket().setReuseAddress(true);
        mSelector = Selector.open();
        mChannel.register(mSelector, SelectionKey.OP_READ);
    }


    @Override
    public void run() {
        isRunning = true;
        while (isRunning) {
            try {
                int n = mSelector.select(200);
                if (n > 0) {
                    Iterator iterator = mSelector.selectedKeys().iterator();
                    while (iterator.hasNext()) {
                        SelectionKey key = (SelectionKey) iterator.next();
                        if (key.isReadable()) {
                            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                            DatagramChannel datagramChannel = (DatagramChannel) key.channel();
                            byteBuffer.clear();
                            InetSocketAddress address = (InetSocketAddress) datagramChannel.receive(byteBuffer);
                            final String data = new String(byteBuffer.array());
                            byteBuffer.flip();
                            final String ip = address.getHostString();
                            mController.processPacket(ip, data);
                        }

                        iterator.remove();
                    }
                }
            } catch (Exception e) {
                Log.e(TAG, "udp server run exception:" + e.toString());
                e.printStackTrace();
            }
        }
    }


    public void stopServer() {
        isRunning = false;
        try{
            if(null != mChannel && mChannel.isOpen()){
                mChannel.close();
            }
        }catch(IOException e) {
            e.printStackTrace();
        }
    }

}